package zsy.test.java.util.concurrent.future;

import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 多平台商品比价模拟 - 获取多个平台相同商品的价格，每次查询耗时1s
 * see {@link #getPrice(List, String)} 依次查询每个平台商品的价格
 * see {@link #getPriceCompletableFuture(List, String)} 异步多任务查询平台商品价格
 *
 * @author zhangshuaiyin
 * @date 2022/6/7 23:04
 */
public class CompletableFutureDemo {
    static List<NetMall> mallList = Arrays.asList(
            new NetMall("jd"),
            new NetMall("tb"),
            new NetMall("dd"),
            new NetMall("pdd"),
            new NetMall("tm")
    );

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        getPrice(mallList, "mysql").forEach(System.out::println);
        System.out.println("cost time: " + (System.currentTimeMillis() - start) + "ms");

        start = System.currentTimeMillis();
        getPriceCompletableFuture(mallList, "mysql").forEach(System.out::println);
        System.out.println("cost time: " + (System.currentTimeMillis() - start) + "ms");
    }

    public static List<String> getPrice(List<NetMall> mallList, String productName) {
        return mallList.stream()
                .map(mall -> String.format("%s in %s 's price is %.2f", productName, mall.getMallName(), mall.calcPrice(productName)))
                .collect(Collectors.toList());
    }

    public static List<String> getPriceCompletableFuture(List<NetMall> mallList, String productName) {
        return mallList.stream()
                .map(mall -> CompletableFuture.supplyAsync(() -> String.format("%s in %s 's price is .2%f", productName, mall.getMallName(), mall.calcPrice(productName))))
                .collect(Collectors.toList())
                .stream()
                .map(CompletableFuture::join)
                .collect(Collectors.toList());
    }

    @Getter
    @AllArgsConstructor
    static class NetMall {
        private String mallName;

        public double calcPrice(String productName) {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return ThreadLocalRandom.current().nextDouble() * 2 + productName.charAt(0);
        }

    }
}

